
//CTest.java

import com.mongodb.*;
import org.apache.log4j.Logger;

import javax.json.Json;
import javax.json.stream.JsonParser;
import java.io.File;
import java.io.FileWriter;
import java.io.StringReader;
import java.math.BigDecimal;
import java.util.*;

import static java.util.concurrent.TimeUnit.SECONDS;






public class CTest {
    
    private final static Logger log = Logger.getLogger(CTest.class);
    
    public static void main( String args[])
    {

        
        try {
            MongoClient mongoClient = new MongoClient( "localhost" );

            DB db = mongoClient.getDB( "base_21090_5000");
	    //DB db = mongoClient.getDB( "base_21090_10000");
            //DB db = mongoClient.getDB( "base_21090_20000");

            DBCollection coll = db.getCollection("base5000");
            //DBCollection coll = db.getCollection("base10000");            
	    //DBCollection coll = db.getCollection("base20000");

            log.debug("start");
            DBCursor cursor = null;// = coll.find();
            
           
            try {

		
		//QUERY 1
		BasicDBObject bdbo1 = new BasicDBObject("ns3:EHRExtract.subjectOfCare.extension","ANON_SERV_RSC:0000000002");

                BasicDBObject proy = new BasicDBObject("ns3:EHRExtract.allCompositions.content.items.parts.parts.archetypeId.root","CEN-EN13606-CLUSTER.Problema-SELENE.v1");               

		proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.name.ns2:originalText.value","Descripciin");
                proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.ns2:originalText.value","OTALGIA");
                


		/* QUERY 2
		BasicDBObject bdbo1 = new BasicDBObject("ns3:EHRExtract.allCompositions.content.items.parts.parts.name.ns2:originalText.value","Descripciin");
                BasicDBObject ind1 = new BasicDBObject("ns3:EHRExtract.subjectOfCare.extension",1);
                BasicDBObject ind2 = new BasicDBObject("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.ns2:originalText.value",1);
                coll.createIndex(ind1,ind2);

                BasicDBObject proy = new BasicDBObject("ns3:EHRExtract.allCompositions.content.items.parts.parts.archetypeId.root","CEN-EN13606-CLUSTER.Problema-SELENE.v1");               

		proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.name.ns2:originalText.value","Descripciin");
                proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.ns2:originalText.value","OTALGIA");
                
                proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.value","OTALGIA");
                proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.nullFlavor","OTALGIA");
		*/

		
		/* QUERY 3
		BasicDBObject bdbo1 = new BasicDBObject("ns3:EHRExtract.subjectOfCare.extension","ANON_SERV_RSC:0000004714");

                BasicDBObject proy = new BasicDBObject("ns3:EHRExtract.allCompositions.content.items.parts.parts.archetypeId.root","CEN-EN13606-CLUSTER.Problema-SELENE.v1");               

		proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.name.ns2:originalText.value","Descripciin");
                proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.ns2:originalText.value","OTALGIA");

		proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.value","OTALGIA");
                proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.nullFlavor","OTALGIA");
		
                */
 

		/* QUERY 4
		BasicDBObject bdbo1 = new BasicDBObject("ns3:EHRExtract.subjectOfCare.extension","ANON_SERV_RSC:0000004154");

                BasicDBObject proy = new BasicDBObject("ns3:EHRExtract.allCompositions.content.items.parts.parts.archetypeId.root","CEN-EN13606-CLUSTER.Problema-SELENE.v1");               

		proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.name.ns2:originalText.value","Descripciin");
                proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.ns2:originalText.value","OTALGIA");

		proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.value","OTALGIA");
                proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.nullFlavor","OTALGIA");
		
                */
               

		/* QUERY 5
		BasicDBObject bdbo1 = new BasicDBObject("ns3:EHRExtract.allCompositions.content.items.parts.parts.name.ns2:originalText.value","Descripciin");
                BasicDBObject ind1 = new BasicDBObject("ns3:EHRExtract.subjectOfCare.extension",1);
                BasicDBObject ind2 = new BasicDBObject("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.ns2:originalText.value",1);
                coll.createIndex(ind1,ind2);

                BasicDBObject proy = new BasicDBObject("ns3:EHRExtract.allCompositions.content.items.parts.parts.archetypeId.root","CEN-EN13606-CLUSTER.Problema-SELENE.v1");               

		proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.name.ns2:originalText.value","Descripciin");
                proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.ns2:originalText.value","OTALGIA");
                
                proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.value","OTALGIA");
                proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.nullFlavor","OTALGIA");
		*/


		/* QUERY 6
		BasicDBObject bdbo1 = new BasicDBObject("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.ns2:originalText.value","FARINGITIS");
                BasicDBObject ind1 = new BasicDBObject("ns3:EHRExtract.subjectOfCare.extension",1);
                BasicDBObject ind2 = new BasicDBObject("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.ns2:originalText.value",1);
                coll.createIndex(ind1,ind2);

                BasicDBObject proy = new BasicDBObject("ns3:EHRExtract.allCompositions.content.items.parts.parts.archetypeId.root","CEN-EN13606-CLUSTER.Problema-SELENE.v1");               
		
                proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.value","OTALGIA");
                proy.append("ns3:EHRExtract.allCompositions.content.items.parts.parts.value.nullFlavor","OTALGIA");
		*/
		
                
                DBObject query4 = new BasicDBObject();
                List<BasicDBObject> andQuery4 = new ArrayList<BasicDBObject>();

                andQuery4.add(bdbo1);
                
                query4.put("$or",andQuery4);


                QueryBuilder qb4 = QueryBuilder.start();

                
                qb4.elemMatch(query4);


                DBObject qq5 = qb4.get();


                String ruta = "C:\\output.txt";

                File hsalida = new File(ruta);

                
                FileWriter to = new FileWriter(hsalida);

                
                cursor = coll.find(query4,proy);

                log.debug("end");

                

                
                while(cursor.hasNext())
                {
                    //Q1
                    parseaFicheroString(to,cursor.next().toString(),"$oid","Descripciin",null,"==","Fecha de apariciin inicial",null,">=","Fecha de resoluciin",null,">=","Severidad",null,"==",2); 
		    
		    //Q2
		    //parseaFicheroString(to,cursor.next().toString(),"$oid","Descripciin",null,"==","Fecha de aparicion inicial",null,">=","Fecha de resolucion",null,">=","Severidad",null,"==",2); 
		    
		    //Q3
                    //parseaFicheroString(to,cursor.next().toString(),"$oid","Descripciin","LUMBALGIA (SIN IRRADIACION)","==","Fecha de apariciin inicial",null,">=","Fecha de resoluciin",null,">=","Severidad",null,"==",5); 
		    
		    //Q4
		    //parseaFicheroString(to,cursor.next().toString(),"$oid","Descripciin",null,"==","Fecha de apariciin inicial",null,">=","Fecha de resoluciin",null,">=","Severidad",null,"==",5); 
		    
		    //Q5
                    //parseaFicheroString(to,cursor.next().toString(),"$oid","Descripciin",null,"==","Fecha de apariciin inicial",null,">=","Fecha de resoluciin",null,">=","Severidad",null,"==",5); 
		    
		    //Q6
                    //parseaFicheroString(to,cursor.next().toString(),"$oid","Descripciin","FARINGITIS","==","Fecha de aparicion inicial","20071016000000.0",">=","Fecha de resolucion","20080506000000.0",">=","Severidad","Muy severo","==",5);
        
                }

                to.close();
		log.debug("number of results "+cursor.count());
                log.debug("adios");


            }
            catch(Exception ex)
            {
                ex.printStackTrace();
            }
            finally {
               cursor.close();
            }



        }
            catch(Exception ex)
            {
                ex.printStackTrace();
            }




    }



    //This method parses and processes the JSON output produced by mongoDB in order to produce a relational table-like text file 
    public static void parseaFicheroString(FileWriter to, String bsonstr, String oid, String sele1, String value1, String op1,String sele2, String value2, String op2, String sele3, String value3, String op3, String sele4, String value4, String op4, int dim)
    {
        
        Array [] tabla = new Array[dim];
        
        

        try {

            JsonParser parser = Json.createParser(new StringReader(bsonstr));


            int n =0;
            int max = 0;
            int t = 0;
            int nivel = 0;
            int flag_descripcion = 0;
            int nivel_archetype = 0;
            int flag_archetype = 0;
            int flag_oid = 0;
            int flag_fecha_de_aparicion_inicial = 0;
            int flag_fecha_de_resolucion = 0;
            int flag_origen = 0;
            for (int i=0; i<dim;i++)
            {
                tabla[i] = null;
            }
            while(parser.hasNext())
            {
                JsonParser.Event ev = parser.next();
                if(ev.name().equals("START_OBJECT"))
                {
                    n++;
                }

                if(ev.name().equals("KEY_NAME"))
                {
                    

                    if(parser.getString().equals("$oid"))
                    {
                        nivel = n;
                        flag_oid = 1;
                    }

                    if(parser.getString().equals("value" ))
                    {
                        nivel = n;
                    }

                    if(parser.getString().equals("root" ))
                    {
                        nivel_archetype = n;
                    }

                    if(parser.getString().equals("nullFlavor"))
                    {
                        nivel = n;
                    }
                }

                if(ev.name().equals("VALUE_STRING"))
                {
                    String cadena = parser.getString();
                    if(nivel_archetype == n)
                    {
                        if(flag_archetype ==0)
                        {
                            if(cadena.equals("CEN-EN13606-CLUSTER.Problema-SELENE.v1"))
                            {
                                flag_archetype = 1;
                            }
                            else
                            {
                                flag_archetype = 0;
                            }
                        }
                    }
                    if(nivel ==n)
                    {
                        
                        {
                            if((cadena.equals(sele1))&&(flag_archetype==1))
                            {
                                flag_descripcion = 1;
                            }
                            else
                            {
                                if((cadena.equals(sele2))&&(flag_archetype==1))
                                {
                                    flag_fecha_de_aparicion_inicial = 1;
                                }
                                else
                                {
                                    if((cadena.equals(sele3))&&(flag_archetype==1))
                                    {
                                        flag_fecha_de_resolucion = 1;
                                    }
                                    else
                                    {
                                        if((cadena.equals(sele4))&&(flag_archetype==1))
                                        {
                                            flag_origen = 1;
                                        }
                                        else
                                        {
                                            if(!cadena.equals("CEN-EN13606-CLUSTER.Problema-SELENE.v1"))
                                            {
                                                if(flag_oid == 1)
                                                {
                                                    if(dim>0)
                                                    {
                                                        if(oid.equals("$oid"))
                                                        {
                                                            tabla[0] = new Array(true,cadena);
                                                        }
                                                        else
                                                        {
                                                            if(cadena.equals(oid))
                                                            {
                                                                tabla[0] = new Array(true,oid);
                                                            }
                                                            else
                                                            {
                                                                tabla[0] =new Array(false,null);
                                                            }
                                                        }
                                                    }
                                                    
                                                    flag_oid = 0;
                                                    nivel = 0;

                                               }
                                                else
                                                {


                                                    if((flag_descripcion ==1)&&(flag_archetype == 1))
                                                    {
                                                        
                                                        if(dim>1)
                                                        {
                                                            if(value1==null)
                                                            {
                                                                tabla[1] = new Array(true,cadena);    
                                                            }
                                                            else
                                                            {
                                                                if(op1.equals("=="))
                                                                {
                                                                    if(cadena.equals(value1))
                                                                    {
                                                                        tabla[1] = new Array(true,value1);
                                                                    }
                                                                    else
                                                                    {
                                                                        tabla[1] = new Array(false,null);
                                                                    }
                                                                }
                                                                
                                                            }
                                                        }
                                                        
                                                        
                                                        flag_descripcion = 0;
                                                        nivel = 0;

                                                        if(dim == 2)
                                                        {
                                                            int contador = 0;
                                                            for(int i =0; i<dim;i++)
                                                            {
                                                                if((tabla[i]!=null)&&(tabla[i].voto))
                                                                    contador++;
                                                            }
                                                            if(contador >= dim)
                                                            {
                                                                for(int j = 0; j<dim; j++)
                                                                {
                                                                    to.write(tabla[j].cadena);
                                                                    to.write("\n");


                                                                }
                                                                tabla[dim-1]=null;
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        if((flag_fecha_de_aparicion_inicial == 1)&&(flag_archetype == 1))
                                                        {
                                                            if(dim>2)
                                                            {
                                                                if(value2==null)
                                                                {
                                                                    tabla[2] = new Array(true,cadena);
                                                                }
                                                                else
                                                                {
                                                                    if(op2.equals(">="))
                                                                    {
                                                                        if(!cadena.equals(value2))
                                                                        {
                                                                            tabla[2] = new Array(true,cadena);
                                                                        }
                                                                        else
                                                                        {
                                                                            tabla[2] = new Array(false, null);
                                                                        }

                                                                    }
                                                                    
                                                                }
                                                            }


                                                            flag_fecha_de_aparicion_inicial = 0;
                                                            nivel = 0;

                                                            if(dim == 3)
                                                            {
                                                                int contador = 0;
                                                                for(int i =0; i<dim;i++)
                                                                {
                                                                    if((tabla[i]!=null)&&(tabla[i].voto))
                                                                        contador++;
                                                                }
                                                                if(contador >= dim)
                                                                {
                                                                    for(int j = 0; j<dim; j++)
                                                                    {
                                                                        to.write(tabla[j].cadena);
                                                                        to.write("\n");


                                                                    }
                                                                    tabla[dim-1]=null;
                                                                }
                                                            }
                                                        }
                                                        else
                                                        {
                                                            if((flag_fecha_de_resolucion == 1)&&(flag_archetype == 1))
                                                            {
                                                                if(dim>3)
                                                                {

                                                                    if(value3==null)
                                                                    {
                                                                        tabla[3] = new Array(true,cadena);
                                                                    }
                                                                    else
                                                                    {
                                                                        if(op3.equals(">="))
                                                                        {
                                                                            if(!cadena.equals(value3))
                                                                            {
                                                                                tabla[3] = new Array(true,cadena);
                                                                            }
                                                                            else
                                                                            {
                                                                                tabla[3] = new Array(false,null);
                                                                            }
                                                                        }
                                                                        
                                                                    }


                                                                }

                                                                flag_fecha_de_resolucion = 0;
                                                                nivel = 0;

                                                                if(dim == 4)
                                                                {
                                                                    int contador = 0;
                                                                    for(int i =0; i<dim;i++)
                                                                    {
                                                                        if((tabla[i]!=null)&&(tabla[i].voto))
                                                                            contador++;
                                                                    }
                                                                    if(contador >= dim)
                                                                    {
                                                                        for(int j = 0; j<dim; j++)
                                                                        {
                                                                            to.write(tabla[j].cadena);
                                                                            to.write("\n");


                                                                        }
                                                                        tabla[dim-1]=null;
                                                                    }
                                                                }


                                                            }
                                                            else
                                                            {
                                                                if((flag_origen == 1)&&(flag_archetype == 1))
                                                                {

                                                                    if(dim > 4)
                                                                    {

                                                                        if(value4==null)
                                                                        {
                                                                            tabla[4] = new Array(true,cadena);
                                                                        }
                                                                        else
                                                                        {
                                                                            if(op4.equals("=="))
                                                                            {
                                                                                if(cadena.equals(value4))
                                                                                {
                                                                                    tabla[4] = new Array(true,cadena);
                                                                                }
                                                                                else
                                                                                {
                                                                                    tabla[4] = new Array(false,null);
                                                                                }
                                                                            }
                                                                            
                                                                        }

                                                                    }


                                                                    flag_origen = 0;
                                                                    nivel = 0;

                                                                    if(dim == 5)
                                                                    {
                                                                        int contador = 0;
                                                                        for(int i =0; i<dim;i++)
                                                                        {
                                                                            if((tabla[i]!=null)&&(tabla[i].voto))
                                                                                contador++;
                                                                        }
                                                                        if(contador >= dim)
                                                                        {
                                                                            for(int j = 0; j<dim; j++)
                                                                            {
                                                                                to.write(tabla[j].cadena);
                                                                                to.write("\n");


                                                                            }
                                                                            tabla[dim-1]=null;
                                                                        }
                                                                    }


                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                
                if(ev.name().equals("VALUE_NUMBER"))
                {
                    if(nivel == n)
                    {

                        if((flag_fecha_de_aparicion_inicial == 1)&&(flag_archetype == 1))
                        {
                            String problema = parser.getBigDecimalValue().toString();

                            

                            if(dim>2)
                            {
                                if(value2==null)
                                {
                                    tabla[2] = new Array(true,problema);
                                }
                                else
                                {
                                    if(op2.equals(">="))
                                    {
                                        if(!problema.equals(value2))
                                        {
                                            tabla[2] = new Array(true,problema);
                                        }
                                        else
                                        {
                                            tabla[2] = new Array(false,null);
                                        }
                                    }
                                    
                                }
                            }


                            flag_fecha_de_aparicion_inicial = 0;
                            nivel = 0;

                            if(dim == 3)
                            {
                                int contador = 0;
                                for(int i =0; i<dim;i++)
                                {
                                    if((tabla[i]!=null)&&(tabla[i].voto))
                                        contador++;
                                }
                                if(contador >= dim)
                                {
                                    for(int j = 0; j<dim; j++)
                                    {
                                        to.write(tabla[j].cadena);
                                        to.write("\n");


                                    }
                                    tabla[dim-1]=null;
                                }
                            }


                        }
                    }
                    
                }



                if(ev.name().equals("END_OBJECT"))
                {
                    n--;
                }
            }

            parser.close();

        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
}


    

